//package com.aman.nikoladespotoski;
//
//import android.content.Context;
//import android.content.res.TypedArray;
//import android.os.Parcelable;
//import android.support.annotation.NonNull;
//import android.support.design.widget.CoordinatorLayout;
//import android.support.v4.view.WindowInsetsCompat;
//import android.text.TextUtils;
//import android.util.AttributeSet;
//import android.view.MotionEvent;
//import android.view.View;
//
//import com.aman.transformer.sample.R;
//
//import java.lang.reflect.Constructor;
//import java.lang.reflect.InvocationTargetException;
//import java.lang.reflect.Method;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
//import static android.R.attr.format;
//
///**
// * Created by Nikola on 4/8/2016.
// */
//public class MultiCoordinatorLayoutBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {
//    static final Class<?>[] CONSTRUCTOR_PARAMS = new Class<?>[]{
//            Context.class,
//            AttributeSet.class
//    };
//    static final ThreadLocal<Map<String, Constructor<CoordinatorLayout.Behavior>>> sConstructors =
//            new ThreadLocal<>();
//    static final ThreadLocal<Map<CoordinatorLayout.Behavior, List<Method>>> sMethod =
//            new ThreadLocal<>();
//
//    private List<CoordinatorLayout.Behavior> mBehaviors = new ArrayList<>();
//
//    public MultiCoordinatorLayoutBehavior() {
//        super();
//    }
//
//    public MultiCoordinatorLayoutBehavior(Context context, AttributeSet attrs) {
//        super(context, attrs);
//        TypedArray a = context.obtainStyledAttributes(attrs,
//                R.styleable.MultiCoordinatorLayoutBehavior);
//        int resourceId = a.getResourceId(R.styleable.MultiCoordinatorLayoutBehavior_behaviors, 0);
//        a.recycle();
//        if (resourceId != 0) {
//            String[] stringArray = context.getResources().getStringArray(resourceId);
//            insantiateBehaviors(context, attrs, stringArray);
//        }
//    }
//
//    static CoordinatorLayout.Behavior parseBehavior(Context context, AttributeSet attrs, String name) {
//        if (TextUtils.isEmpty(name)) {
//            return null;
//        }
//
//        final String fullName;
//        if (name.startsWith(".")) {
//            fullName = context.getPackageName() + name;
//        } else if (name.indexOf('.') >= 0) {
//            fullName = name;
//        } else {
//            fullName = '.' + name;
//        }
//
//        try {
//            Map<String, Constructor<CoordinatorLayout.Behavior>> constructors = sConstructors.get();
//            if (constructors == null) {
//                constructors = new HashMap<>();
//                sConstructors.set(constructors);
//            }
//            Constructor<CoordinatorLayout.Behavior> c = constructors.get(fullName);
//            if (c == null) {
//                final Class<CoordinatorLayout.Behavior> clazz = (Class<CoordinatorLayout.Behavior>) Class.forName(fullName, true,
//                        context.getClassLoader());
//                c = clazz.getConstructor(CONSTRUCTOR_PARAMS);
//                c.setAccessible(true);
//                constructors.put(fullName, c);
//            }
//            return c.newInstance(context, attrs);
//        } catch (Exception e) {
//            throw new RuntimeException("Could not inflate Behavior subclass " + fullName, e);
//        }
//    }
//
//
//    @Override
//    public Parcelable onSaveInstanceState(CoordinatorLayout parent, V child) {
//        return super.onSaveInstanceState(parent, child);
//    }
//
//    @Override
//    public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev) {
//        return super.onInterceptTouchEvent(parent, child, ev);
//    }
//
//    @Override
//    public boolean onTouchEvent(CoordinatorLayout parent, V child, MotionEvent ev) {
//        return super.onTouchEvent(parent, child, ev);
//    }
//
//    @Override
//    public int getScrimColor(CoordinatorLayout parent, V child) {
//        return super.getScrimColor(parent, child);
//    }
//
//    @Override
//    public float getScrimOpacity(CoordinatorLayout parent, V child) {
//        return super.getScrimOpacity(parent, child);
//    }
//
//    @Override
//    public boolean blocksInteractionBelow(CoordinatorLayout parent, V child) {
//        return super.blocksInteractionBelow(parent, child);
//    }
//
//    @Override
//    public boolean layoutDependsOn(CoordinatorLayout parent, V child, View dependency) {
//        return super.layoutDependsOn(parent, child, dependency);
//    }
//
//    @Override
//    public boolean onDependentViewChanged(CoordinatorLayout parent, V child, View dependency) {
//        return super.onDependentViewChanged(parent, child, dependency);
//    }
//
//    @Override
//    public void onDependentViewRemoved(CoordinatorLayout parent, V child, View dependency) {
//        super.onDependentViewRemoved(parent, child, dependency);
//    }
//
//    @Override
//    public boolean isDirty(CoordinatorLayout parent, V child) {
//        return super.isDirty(parent, child);
//    }
//
//    @Override
//    public boolean onMeasureChild(CoordinatorLayout parent, V child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
//        return super.onMeasureChild(parent, child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
//    }
//
//    @Override
//    public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
//        return super.onLayoutChild(parent, child, layoutDirection);
//    }
//
//    @Override
//    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) {
//        return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
//    }
//
//    @Override
//    public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) {
//        super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
//    }
//
//    @Override
//    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
//        super.onStopNestedScroll(coordinatorLayout, child, target);
//    }
//
//    @Override
//    public void onNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
//        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
//    }
//
//    @Override
//    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) {
//        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
//    }
//
//    @Override
//    public boolean onNestedFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, boolean consumed) {
//        invokeMethod("onNestedFling", coordinatorLayout, child, target, velocityX, velocityY, consumed);
//        return true;
//    }
//
//    @Override
//    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY) {
//        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
//    }
//
//    @Override
//    public WindowInsetsCompat onApplyWindowInsets(CoordinatorLayout coordinatorLayout, V child, WindowInsetsCompat insets) {
//        return super.onApplyWindowInsets(coordinatorLayout, child, insets);
//    }
//
//    @Override
//    public void onRestoreInstanceState(CoordinatorLayout parent, V child, Parcelable state) {
//        super.onRestoreInstanceState(parent, child, state);
//    }
//
//    private void insantiateBehaviors(Context context, AttributeSet attrs, @NonNull String[] behaviors) {
//        for (int i = behaviors.length - 1; i >= 0; i--) {
//            CoordinatorLayout.Behavior behavior = parseBehavior(context, attrs, behaviors[i]);
//            if (behavior != null) {
//                mBehaviors.add(behavior);
//            }
//        }
//    }
//
//    private void invokeMethod(String methodName, Object... params) {
//        for (int i = mBehaviors.size() - 1; i >= 0; i--) {
//            CoordinatorLayout.Behavior behavior = mBehaviors.get(i);
//            Map<CoordinatorLayout.Behavior, List<Method>> methodsMap = sMethod.get();
//            List<Method> methods = methodsMap.get(behavior);
//            if (methods == null) {
//                methods = resolveAllMethods(behavior);
//                methodsMap.put(behavior, methods);
//            }
//            Method method = getMethod(methods, methodName);
//            if (method != null && method.isAccessible()) {
//                try {
//                    method.invoke(behavior, params);
//                } catch (IllegalAccessException e) {
//                    e.printStackTrace();
//                } catch (InvocationTargetException e) {
//                    e.printStackTrace();
//                }
//            }
//
//        }
//    }
//
//    private List<Method> resolveAllMethods(CoordinatorLayout.Behavior behavior) {
//        Method[] declaredMethods = behavior.getClass().getDeclaredMethods();
//        return Arrays.asList(declaredMethods);
//    }
//
//
//    private Method getMethod(List<Method> methods, String methodName) {
//        for (int i = methods.size() - 1; i >= 0; i--) {
//            Method method = methods.get(i);
//            if (method.getName().toLowerCase().equals(methodName)) return method;
//        }
//        return null;
//    }
//
//}